﻿// See https://aka.ms/new-console-template for more information
//命令模式
//命令模式将请求与请求接收者解耦，请求发送者通过命令对象来间接引用接收者，使得系统具有更好的灵活性。
//他使得我们能够将请求封装成一个对象，从而使得我们可以使用不同的请求，队列或日志来参数化其他对象。命令模式还支持可撤销操作。

//在现实生活中，人们通过使用开关来控制一些电器的打开和关闭，例如电灯或者电风扇。在购买开关时，购买者并不需要知道他将来会控制什么电器，也就是说开关本身和电器是没有直接关系的。一个开关在安装之后可能会用来控制电灯，也可能会用来控制电风扇，这一切都取决于你如何栓电线。我们可以将开关理解为请求的发出者，电灯或者电风扇理解为请求的处理者。开关和电灯直接没有直接关系，他们通过电线产生联系，当我们想让开关控制电风扇时，我们让电线链接开关和电风扇即可。

//该模式涉及三个主要角色：
//·命令（Command）：封装请求的对象，包括请求执行的方法和参数。
//·接收者（Receiver）：知道如何执行命令的对象。
//·调用者（Invoker）：负责创建并将命令对象传递给接收者执行。
//命令模式的核心思想是将请求和执行请求的对象分离。命令对象将请求封装到自己的对象中，从而使命令对象不同于发出请求的对象。这使我们可以轻松的在不同的情况下使用不同的命令对象。

//创建一个接收者对象
var receiver = new Receiver();
//创建一个具体命令对象并传入接收者对象
var command=new ConcreteCommand(receiver);
//创建一个调用者对象并设置具体命令对象
var invoker = new Invoker();
invoker.SetCommand(command);

//执行命令
invoker.ExecuteCommand();



Console.WriteLine("Hello, World!");

//抽象命令类
public abstract class Command
{
    public abstract void Execute();
}

//接收者类
public class Receiver
{
    public void Action()
    {
        Console.WriteLine("Receiver:Performing action...");
    }
}

//具体命令类
public class ConcreteCommand : Command
{
    private Receiver _receiver;

    public ConcreteCommand(Receiver receiver)
    {
        _receiver= receiver;
    }
    public override void Execute()
    {
        Console.WriteLine("ConcreteCommand：Createing and executing the command...");
        _receiver.Action();
    }
}

//调用者类
public class Invoker
{
    private Command _command;
    public void SetCommand(Command command)
    {
        _command= command;
    }
    public void ExecuteCommand()
    {
        Console.WriteLine("Invoker:Execting command...");
        _command.Execute();
    }
}